/*
 Copyright (c) 2014 ABB Group
 All rights reserved. This program and the accompanying materials
 are made available under the terms of the Eclipse Public License v1.0
 which accompanies this distribution, and is available at
 http://www.eclipse.org/legal/epl-v10.html
 
 Contributors:
    Christian Manteuffel (University of Groningen)
    Spyros Ioakeimidis (University of Groningen)
    Antonis Gkortzis (University of Groningen)   
    Mark Hoekstra (University of Groningen)
    K. Eric Harper (ABB Corporate Research)
*/

using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using DecisionArchitect.Logic;
using DecisionArchitect.Logic.EventHandler;
using DecisionArchitect.Model;
using DecisionArchitect.Utilities;
using DecisionArchitect.View.Dialogs;
using EAFacade;
using EAFacade.Model;

namespace DecisionArchitect.View.Forces
{
    [ComVisible(true)]
    [Guid("B2219386-7889-4250-86A5-74760300A1F8")]
    [ClassInterface(ClassInterfaceType.None)]
    [ComDefaultInterface(typeof (IForcesView))]
    [ProgId("DecisionViewpoints.Forces")]
    public class ForcesView : UserControl, IForcesView
    {
        private Button _btnAddDecision;
        private Button _btnAddForce;
        private Button _btnConfigure;
        private Button _btnOpenExcel;
        private IForcesController _controller;
        private CheckBox _chkShowScenarios;
        private DataGridView _forcesTable;
        private static List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IEAElement, IForcesView>> _forcesClipboard;
        private static List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IForcesView>> _decisionsClipboard;

        public ForcesView()
        {
            InitializeComponent();

            if(null == _forcesClipboard)
            {
                // Tuple members: clipboard operation, selected row, source diagram, force, concern
                _forcesClipboard = new List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IEAElement, IForcesView>>();
            }

            if (null == _decisionsClipboard)
            {
                // Tuple members: clipboard operation, selected column, source diagram, decision
                _decisionsClipboard = new List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IForcesView>>();
            }
        }

        public void UpdateTable(IForcesModel model)
        {
            //deactivate cell value listener
            _forcesTable.CellValueChanged -= _forcesTable_CellValueChanged;

            var data = new DataTable();

            // the first four columns are:
            // ForceGUID, Concern, ClassifiedByGUID, ConcernGUID
            // Order must match index order in ForcesTableContext
            data.Columns.Add(ForcesTableContext.ForceGUIDHeader);
            data.Columns.Add(ForcesTableContext.ConcernHeader);
            data.Columns.Add(ForcesTableContext.ClassifiedByGUIDHeader);
            data.Columns.Add(ForcesTableContext.ConcernGUIDHeader);

            if(!_controller.Model.ScenarioView)
            {
                // insert the decisions names as new columns in the table
                InsertDecisions(model, data);
            }
            else
            {
                // insert the force scenario labels as new columns in the table
                InsertScenarioLabels(model, data);
            }

            // insert the force guids, force, concerns and concerns guids
            _forcesTable.DataSource = data;
            InsertForcesAndConcerns(model, data);

            _forcesTable.DataSource = data;
            if (!_controller.Model.ScenarioView)
            {
                // insert the decision guids in the table
                data.Rows.Add(new object[]
                {
                    // Add an entry for each column that is not a decision
                    ForcesTableContext.EmptyCellValue, ForcesTableContext.EmptyCellValue,
                    ForcesTableContext.EmptyCellValue, ForcesTableContext.EmptyCellValue
                });
                InsertDecisionGuids(model, data);
                _forcesTable.Rows[_forcesTable.Rows.Count - 1].HeaderCell.Value = ForcesTableContext.DecisionGUIDHeader;
                HideRow(_forcesTable.Rows.Count - 1);
            }

            if (data.Columns.Count <= 0) return;

            // hide the columns and row which contain the guids of the elements
            HideColumn(ForcesTableContext.ForceGUIDHeader);
            HideColumn(ForcesTableContext.ConcernGUIDHeader);
            HideColumn(ForcesTableContext.ClassifiedByGUIDHeader);
            ReadOnlyColumn(ForcesTableContext.ConcernHeader);

            if (!_controller.Model.ScenarioView)
            {
                foreach (DataGridViewColumn column in _forcesTable.Columns)
                {
                    column.SortMode = DataGridViewColumnSortMode.NotSortable;
                    // Colour decision header
                    ColourDecisionHeader(_forcesTable.Columns.IndexOf(column));
                }
            }

            //Colour each row header
            foreach (DataGridViewRow row in _forcesTable.Rows)
            {
                ColourForceHeader(_forcesTable.Rows.IndexOf(row));
            }

            if(!_controller.Model.ScenarioView)
            {
                // insert the ratings in the table
                InsertRatings(model, data);
            }
            else
            {
                // insert the descriptions in the table
                InsertScenarios(model, data);
            }

            //activate cell value listener
            _forcesTable.Columns[0].Frozen = true;
            _forcesTable.Columns[1].Frozen = true;
            _forcesTable.CellValueChanged += _forcesTable_CellValueChanged;

            //Update view
            Invalidate();

            IsDirty = false;
        }

        /// <summary>
        ///     Update a decision's name and its colour
        /// </summary>
        /// <param name="element"></param>
        public void UpdateDecision(IEAElement element)
        {
            int columnIndex = 0;
            foreach (DataGridViewCell cell in _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells)
            {
                if (cell.Value.ToString().Equals(element.GUID))
                {
                    _forcesTable.Columns[columnIndex].HeaderText = String.Format("<<{0}>>\n{1}", element.Stereotype,
                                                                                 element.Name);
                    ColourDecisionHeader(columnIndex);
                    break;
                }
                columnIndex++;
            }
        }

        private static string FormatForceCell(IEAElement element)
        {
            string cell = "";
            string category = element.GetTaggedValueByName("DA.Category");
            string stereotype = element.StereotypeList;
            string context = element.GetTaggedValueByName("DA.Context");
            string type = element.GetTaggedValueByName("DA.Type");
            if (null != category && 0 < category.Length)
            {
                cell += "[" + category + "]\n";
            }
            if (null != type && 0 < type.Length)
            {
                cell += "<" + type + ">\n";
            }
            else if (null != stereotype && 0 < stereotype.Length)
            {
                cell += "<<" + stereotype + ">>\n";
            }
            if (null != context && 0 < context.Length)
            {
                cell += context + ": ";
            }
            cell += element.Name;
            return cell;
        }

        private static string FormatConcernCell(IEAElement element)
        {
            string cell = "";
            string category = element.GetTaggedValueByName("DA.Category");
            string context = element.GetTaggedValueByName("DA.Context");
            string type = element.GetTaggedValueByName("DA.Type");
            if (null != category && 0 < category.Length)
            {
                cell += "[" + category + "]\n";
            }
            if (null != type && 0 < type.Length)
            {
                cell += "<" + type + ">\n";
            }
            if (null != context && 0 < context.Length)
            {
                cell += context + ": ";
            }
            cell += element.Name;
            return cell;
        }

        /// <summary>
        ///     Update a force's name and its colour if it's a decision
        /// </summary>
        /// <param name="element"></param>
        public void UpdateForce(IEAElement element)
        {
            int rowIndex = 0;
            foreach (
                DataGridViewRow row in
                    _forcesTable.Rows.Cast<DataGridViewRow>()
                                .Where(
                                    row =>
                                    row.Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString()
                                                                                      .Equals(element.GUID)))
            {
                row.HeaderCell.Value = FormatForceCell(element);
                ColourForceHeader(rowIndex);
                rowIndex++;
            }
        }

        /// <summary>
        ///     Update the concern's name
        /// </summary>
        /// <param name="element"></param>
        public void UpdateConcern(IEAElement element)
        {
            foreach (
                DataGridViewRow row in
                    _forcesTable.Rows.Cast<DataGridViewRow>()
                                .Where(
                                    row =>
                                    row.Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString()
                                                                                        .Equals(element.GUID)))
            {
                row.Cells[ForcesTableContext.ConcernColumnIndex].Value = FormatConcernCell(element);
            }
        }

        /// <summary>
        ///     Remove the decision from the ForcesView
        /// </summary>
        /// <param name="element"></param>
        public void RemoveDecision(IEAElement element)
        {
            IEARepository repository = EAMain.Repository;
            IEADiagram diagram = repository.GetDiagramByGuid(_controller.Model.DiagramGUID);
            RemoveDecisionFromDiagram(element, diagram);
            _controller.SetDiagramModel(diagram);
        }

        /// <summary>
        ///     Remove the force from the ForcesView
        /// </summary>
        /// <param name="element"></param>
        public void RemoveForce(IEAElement element)
        {
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            for (int i = _forcesTable.Rows.Count - 1; i >= 0; i--)
            {
                //Skip other elements
                if (
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.Equals(
                        ForcesTableContext.EmptyCellValue)) continue;
                if (
                    !_forcesTable.Rows[i].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString()
                                                                                        .Equals(element.GUID)) continue;

                // Get the GUIDs for the force and concern
                string forceGuid =
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString();
                string concernGuid =
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString();

                // Get the force and concern objects
                IEAElement force = repository.GetElementByGUID(forceGuid);
                IEAElement concern = repository.GetElementByGUID(concernGuid);

                RemoveForceFromDiagram(force, concern, diagram, EAConnectorDirection.ClientToSupplier, true);
            }

            _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
        }

        /// <summary>
        ///     Remove the concern from the ForcesView (Will remove the force with the concern)
        /// </summary>
        /// <param name="element"></param>
        public void RemoveConcern(IEAElement element)
        {
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            for (int i = _forcesTable.Rows.Count - 1; i >= 0; i--)
            {
                //Skip other elements
                if (
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.Equals(
                        ForcesTableContext.EmptyCellValue)) continue;
                if (
                    !_forcesTable.Rows[i].Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString()
                                                                                          .Equals(element.GUID))
                    continue;

                // Get the GUIDs for the force and concern
                string forceGuid =
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString();
                string concernGuid =
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString();

                // Get the force and concern objects
                IEAElement force = repository.GetElementByGUID(forceGuid);
                IEAElement concern = repository.GetElementByGUID(concernGuid);

                RemoveForceFromDiagram(force, concern, diagram, EAConnectorDirection.ClientToSupplier, true);
            }

            _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
        }

        public string[] ForceGuids
        {
            get
            {
                return
                    _forcesTable.Rows.Cast<DataGridViewRow>()
                                .Select(row => row.Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString())
                                .Where(value => !value.Equals(ForcesTableContext.EmptyCellValue))
                                .ToArray();
            }
        }

        public string[] ConcernGuids
        {
            get
            {
                return _forcesTable.Rows.Cast<DataGridViewRow>()
                                   .Select(row => row.Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString())
                                   .Where(value => !value.Equals(ForcesTableContext.EmptyCellValue))
                                   .ToArray();
            }
        }

        public string[] DecisionGuids
        {
            get
            {
                return _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells.Cast<DataGridViewCell>()
                                                                     .Select(cell => cell.Value.ToString())
                                                                     .Where(
                                                                         value =>
                                                                         !value.Equals(ForcesTableContext.EmptyCellValue))
                                                                     .ToArray();
            }
        }

        public bool IsDirty { get; set; }

        public DataTable GetChanges()
        {
            DataTable orig = (DataTable)_forcesTable.DataSource;
            return orig.GetChanges();
        }

        public string GetRating(int row, int column)
        {
            return _forcesTable[column, row].Value.ToString();
        }

        public void SetController(IForcesController controller)
        {
            _controller = controller;
        }

        public void Update(IForcesModel model)
        {
            UpdateTable(model);
        }

        #region Windows Form Designer generated code

        /// <summary>
        ///     Required method for Designer support - do not modify
        ///     the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
            this._forcesTable = new System.Windows.Forms.DataGridView();
            this._btnConfigure = new System.Windows.Forms.Button();
            this._btnAddDecision = new System.Windows.Forms.Button();
            this._btnOpenExcel = new System.Windows.Forms.Button();
            this._btnAddForce = new System.Windows.Forms.Button();
            this._chkShowScenarios = new System.Windows.Forms.CheckBox();
            ((System.ComponentModel.ISupportInitialize)(this._forcesTable)).BeginInit();
            this.SuspendLayout();
            // 
            // _forcesTable
            // 
            this._forcesTable.AllowUserToAddRows = false;
            this._forcesTable.AllowUserToDeleteRows = false;
            this._forcesTable.AllowUserToResizeColumns = false;
            this._forcesTable.AllowUserToResizeRows = false;
            this._forcesTable.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
            | System.Windows.Forms.AnchorStyles.Left) 
            | System.Windows.Forms.AnchorStyles.Right)));
            this._forcesTable.AutoSizeRowsMode = System.Windows.Forms.DataGridViewAutoSizeRowsMode.AllCells;
            this._forcesTable.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
            this._forcesTable.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
            dataGridViewCellStyle1.BackColor = System.Drawing.SystemColors.Window;
            dataGridViewCellStyle1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            dataGridViewCellStyle1.ForeColor = System.Drawing.SystemColors.ControlText;
            dataGridViewCellStyle1.SelectionBackColor = System.Drawing.SystemColors.Highlight;
            dataGridViewCellStyle1.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
            dataGridViewCellStyle1.WrapMode = System.Windows.Forms.DataGridViewTriState.True;
            this._forcesTable.DefaultCellStyle = dataGridViewCellStyle1;
            this._forcesTable.EnableHeadersVisualStyles = false;
            this._forcesTable.Location = new System.Drawing.Point(0, 32);
            this._forcesTable.Name = "_forcesTable";
            this._forcesTable.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
            this._forcesTable.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
            this._forcesTable.RowTemplate.Height = 33;
            this._forcesTable.Size = new System.Drawing.Size(850, 657);
            this._forcesTable.TabIndex = 2;
            this._forcesTable.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this._forcesTable_CellClick);
            this._forcesTable.CellMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this._forcesTable_CellMouseClick);
            this._forcesTable.CellValueChanged += new System.Windows.Forms.DataGridViewCellEventHandler(this._forcesTable_CellValueChanged);
            this._forcesTable.ColumnHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this._forcesTable_ColumnHeaderMouseClick);
            this._forcesTable.ColumnHeaderMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this._forcesTable_ColumnHeaderMouseDoubleClick);
            this._forcesTable.RowHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this._forcesTable_RowHeaderMouseClick);
            // 
            // _btnConfigure
            // 
            this._btnConfigure.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
            this._btnConfigure.Location = new System.Drawing.Point(772, 3);
            this._btnConfigure.Name = "_btnConfigure";
            this._btnConfigure.Size = new System.Drawing.Size(75, 23);
            this._btnConfigure.TabIndex = 3;
            this._btnConfigure.Text = global::DecisionArchitect.Messages.ForcesViewConfigureButton;
            this._btnConfigure.UseVisualStyleBackColor = true;
            this._btnConfigure.Visible = false;
            this._btnConfigure.Click += new System.EventHandler(this._btnConfigure_Click);
            // 
            // _btnAddDecision
            // 
            this._btnAddDecision.AutoSize = true;
            this._btnAddDecision.FlatAppearance.BorderSize = 0;
            this._btnAddDecision.Location = new System.Drawing.Point(3, 3);
            this._btnAddDecision.Name = "_btnAddDecision";
            this._btnAddDecision.Size = new System.Drawing.Size(80, 23);
            this._btnAddDecision.TabIndex = 4;
            this._btnAddDecision.Text = "Add Decision";
            this._btnAddDecision.UseVisualStyleBackColor = true;
            this._btnAddDecision.Click += new System.EventHandler(this._btnAddDecision_Click);
            // 
            // _btnOpenExcel
            // 
            this._btnOpenExcel.AutoSize = true;
            this._btnOpenExcel.FlatAppearance.BorderSize = 0;
            this._btnOpenExcel.Location = new System.Drawing.Point(173, 3);
            this._btnOpenExcel.Name = "_btnOpenExcel";
            this._btnOpenExcel.Size = new System.Drawing.Size(80, 23);
            this._btnOpenExcel.TabIndex = 5;
            this._btnOpenExcel.Text = "Excel";
            this._btnOpenExcel.UseVisualStyleBackColor = true;
            this._btnOpenExcel.Click += new System.EventHandler(this._btnOpenExcel_Click);
            // 
            // _btnAddForce
            // 
            this._btnAddForce.Location = new System.Drawing.Point(89, 3);
            this._btnAddForce.Name = "_btnAddForce";
            this._btnAddForce.Size = new System.Drawing.Size(80, 23);
            this._btnAddForce.TabIndex = 6;
            this._btnAddForce.Text = "Add Force";
            this._btnAddForce.UseVisualStyleBackColor = true;
            this._btnAddForce.Click += new System.EventHandler(this._btnAddForce_Click);
            // 
            // _chkShowScenarios
            // 
            this._chkShowScenarios.AutoSize = true;
            this._chkShowScenarios.Location = new System.Drawing.Point(271, 8);
            this._chkShowScenarios.Name = "_chkShowScenarios";
            this._chkShowScenarios.Size = new System.Drawing.Size(73, 17);
            this._chkShowScenarios.TabIndex = 7;
            this._chkShowScenarios.Text = "Scenarios";
            this._chkShowScenarios.UseVisualStyleBackColor = true;
            this._chkShowScenarios.CheckedChanged += new System.EventHandler(this._chkShowScenarios_CheckedChanged);
            // 
            // ForcesView
            // 
            this.Controls.Add(this._chkShowScenarios);
            this.Controls.Add(this._btnAddForce);
            this.Controls.Add(this._btnOpenExcel);
            this.Controls.Add(this._btnAddDecision);
            this.Controls.Add(this._btnConfigure);
            this.Controls.Add(this._forcesTable);
            this.Name = "ForcesView";
            this.Size = new System.Drawing.Size(850, 689);
            ((System.ComponentModel.ISupportInitialize)(this._forcesTable)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        /// <summary>
        ///     Colours the header of a decision column according to the state of the decision
        /// </summary>
        /// <param name="i"></param>
        private void ColourDecisionHeader(int i)
        {
            if (i < ForcesTableContext.DecisionColumnIndex) return;
            string decisionGuid = _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells[i].Value.ToString();
            DataGridViewColumn column = _forcesTable.Columns[i];
            if (column.HeaderCell == null) return;
            IEARepository repository = EAMain.Repository;
            column.HeaderCell.Style.BackColor =
                RetrieveColorByState(repository.GetElementByGUID(decisionGuid).Stereotype);
        }

        /// <summary>
        ///     Colours the header of a row according to the state of the element in the row if it is a decision
        /// </summary>
        /// <param name="i"></param>
        private void ColourForceHeader(int i)
        {
            DataGridViewRow row = _forcesTable.Rows[i];
            string guid = row.Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString();
            if (guid.Equals(ForcesTableContext.EmptyCellValue)) return;
            IEARepository repository = EAMain.Repository;
            IEAElement element = repository.GetElementByGUID(guid);
            if (element == null || row.HeaderCell == null || !EAMain.IsDecision(element)) return;
            row.HeaderCell.Style.BackColor = RetrieveColorByState(element.Stereotype);
        }

        /// <summary>
        ///     Retrieves the colour belonging to the state
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        private Color RetrieveColorByState(string state)
        {
            return DecisionStateColor.ConvertStateToColor(state);
        }

        private void ReadOnlyColumn(string header)
        {
            DataGridViewColumn column = _forcesTable.Columns[header];
            if (column != null) column.ReadOnly = true;
        }

        private void HideColumn(string header)
        {
            DataGridViewColumn column = _forcesTable.Columns[header];
            if (column != null)
                column.Visible = false;
        }

        private static void InsertRatings(IForcesModel model, DataTable data)
        {
            foreach (Rating rating in model.GetRatings())
            {
                int decisionColumnIndex = 0;
                for (int index = ForcesTableContext.DecisionColumnIndex; index < data.Columns.Count; index++)
                {
                    if (!data.Rows[data.Rows.Count - 1][index].ToString().Equals(rating.DecisionGUID))
                        continue;
                    decisionColumnIndex = index;
                    break;
                }
                if (decisionColumnIndex == 0) continue;

                foreach (DataRow row in data.Rows)
                {
                    if (row[ForcesTableContext.ForceGUIDColumnIndex].Equals(rating.ForceGUID) &&
                        row[ForcesTableContext.ConcernGUIDColumnIndex].Equals(rating.ConcernGUID))
                    {
                        row[decisionColumnIndex] = rating.Value;
                    }
                }
            }
        }

        private static void InsertScenarios(IForcesModel model, DataTable data)
        {
            foreach (ScenarioElement element in model.GetScenarios())
            {
                int scenarioColumnIndex = ForcesTableContext.DecisionColumnIndex + element.ColumnOffset;

                foreach (DataRow row in data.Rows)
                {
                    if (row[ForcesTableContext.ClassifiedByGUIDColumnIndex].Equals(element.ClassifiedByGUID))
                    {
                        row[scenarioColumnIndex] = element.Value;
                    }
                }
            }
        }

        private void InsertForcesAndConcerns(IForcesModel model, DataTable table)
        {
            int rowIndex = 0;
            foreach (var dictionary in model.GetConcernsPerForce())
            {
                IEAElement force = dictionary.Key;
                List<Tuple<IEAElement,IEAConnector>> suppliers = dictionary.Value;

                foreach (Tuple<IEAElement,IEAConnector> supplier in suppliers)
                {
                    IEAElement concern = supplier.Item1;
                    IEAConnector classifiedBy = supplier.Item2;
                    //in first column add force and concern guid
                    var forceConcernGuid = new object[] {force.GUID};
                    DataRow row = table.Rows.Add(forceConcernGuid);
                    _forcesTable.DataSource = table;
                    _forcesTable.Rows[rowIndex++].HeaderCell.Value = FormatForceCell(force);

                    row[ForcesTableContext.ConcernColumnIndex] = FormatConcernCell(concern);
                    row[ForcesTableContext.ClassifiedByGUIDColumnIndex] = classifiedBy.GUID;
                    row[ForcesTableContext.ConcernGUIDColumnIndex] = concern.GUID;
                }
            }
        }

        private static void InsertDecisionGuids(IForcesModel model, DataTable data)
        {
            int decisionIndex = 0;
            foreach (IEAElement decision in model.GetDecisions())
            {
                if (!decision.TaggedValueExists(EATaggedValueKeys.IsDecisionElement, model.DiagramGUID)) continue;
                data.Rows[data.Rows.Count - 1][decisionIndex++ + ForcesTableContext.DecisionColumnIndex] = decision.GUID;
            }
        }

        private void InsertDecisions(IForcesModel model, DataTable data)
        {
            foreach (IEAElement decision in model.GetDecisions())
            {
                if (!decision.TaggedValueExists(EATaggedValueKeys.IsDecisionElement, model.DiagramGUID)) continue;
                data.Columns.Add(string.Format("<<{0}>>\n{1}", decision.Stereotype, decision.Name));
            }
        }

        private void InsertScenarioLabels(IForcesModel model, DataTable data)
        {
            for( int i = 0; i < ScenarioElement.Label.Length; i++)
            {
                data.Columns.Add(ScenarioElement.Label[i]);
            }
        }

        private void HideRow(int index)
        {
            // we need this to hide the last row for when the table has no rows
            // and it is visible as a tab and the user adds new elements
            _forcesTable.CurrentCell = null;
            _forcesTable.Rows[index].Visible = false;
        }

        private void _forcesTable_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            _controller.Save();
        }

        /// <summary>
        ///     Opens de Detail Viewpoint on double clicking on a header.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _forcesTable_ColumnHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //Only for decisions
            if (e.ColumnIndex < ForcesTableContext.DecisionColumnIndex) return;

            string elementGuid =
                _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells[e.ColumnIndex].Value.ToString();
            IEAElement decision = EAMain.Repository.GetElementByGUID(elementGuid);
            OpenInDetailView(Decision.Load(decision));
        }

        /// <summary>
        ///     Defines MenuItems for a right click on a column's header
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _forcesTable_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            //Only for decisions
            if (e.ColumnIndex < ForcesTableContext.DecisionColumnIndex) return;

            string elementGuid =
                _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells[e.ColumnIndex].Value.ToString();
            IEAElement decision = EAMain.Repository.GetElementByGUID(elementGuid);
            if (e.Button == MouseButtons.Right)
            {
                var menu = new ContextMenu();

                // Menuitem for cutting decisions
                menu.MenuItems.Add(Messages.ForcesViewCutDecision, (sender1, e1) =>
                    CopyDecisionFromDiagram(ForcesTableContext.ClipboardOperation.Cut, decision, e.ColumnIndex));

                // Menuitem for copying decisions
                menu.MenuItems.Add(Messages.ForcesViewCopyDecision, (sender1, e1) =>
                    CopyDecisionFromDiagram(ForcesTableContext.ClipboardOperation.Copy, decision, e.ColumnIndex));

                if (0 < _decisionsClipboard.Count())
                {
                    // Menuitem for pasting decisions
                    menu.MenuItems.Add(Messages.ForcesViewPasteDecision, (sender1, e1) => PasteDecisionToDiagram());
                }

                // Menuitem for a separator
                menu.MenuItems.Add("-");


                // Menuitem for opening a decision in its diagram
                menu.MenuItems.Add(Messages.ForcesViewOpenDecisionInDiagrams,
                                   (o, args) => OpenDecisionInDiagrams(decision));

                // Menuitem for opening the detailviewpoint of a decision
                menu.MenuItems.Add(Messages.ForcesViewOpenDecisionInDetailView,
                                   (sender1, e1) => OpenInDetailView(Decision.Load(decision)));

                // Menuitem for a separator
                menu.MenuItems.Add("-");

                // Menuitem for removing a decision
                menu.MenuItems.Add(Messages.ForcesViewRemoveDecision, (sender1, e1) =>
                    {
                        RemoveDecisionFromDiagram(e.ColumnIndex);
                        IEARepository repository = EAMain.Repository;
                        _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
                    });

                // Meneitem for removing all decision
                menu.MenuItems.Add(Messages.ForcesViewRemoveAllDecisions,
                                   (sender1, e1) => RemoveAllDecisionsFromDiagram());

                Point relativeMousePosition = PointToClient(Cursor.Position);
                menu.Show(this, relativeMousePosition);
            }
        }

        private void OpenDecisionInDiagrams(IEAElement decision)
        {
            IEADiagram[] diagrams = decision.GetDiagrams();
            if (diagrams.Count() == 1) // open the diagram with the decision if there is only one diagram
            {
                IEADiagram diagram = diagrams[0];
                diagram.OpenAndSelectElement(decision);
            }
            else if (diagrams.Count() >= 2) // let the user decide which diagram to open
            {
                var selectForm = new SelectDiagram(diagrams);
                if (selectForm.ShowDialog() == DialogResult.OK)
                {
                    IEADiagram diagram = selectForm.GetSelectedDiagram();
                    diagram.OpenAndSelectElement(decision);
                }
            }
            decision.ShowInProjectView();
        }

        /// <summary>
        ///     Defines MenuItems for right clicking on a row's header
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _forcesTable_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                var menu = new ContextMenu();
                // Menuitem for cutting forces
                menu.MenuItems.Add(Messages.ForcesViewCutForce, (sender1, e1) =>
                    CopySelectedForcesFromDiagram(ForcesTableContext.ClipboardOperation.Cut, _forcesTable.SelectedRows));

                // Menuitem for copying forces
                menu.MenuItems.Add(Messages.ForcesViewCopyForce, (sender1, e1) =>
                    CopySelectedForcesFromDiagram(ForcesTableContext.ClipboardOperation.Copy, _forcesTable.SelectedRows));

                if(0 < _forcesClipboard.Count())
                {
                    // Menuitem for pasting forces
                    menu.MenuItems.Add(Messages.ForcesViewPasteForce, (sender1, e1) => PasteSelectedForcesToDiagram());
                }

                // Menuitem for a separator
                menu.MenuItems.Add("-");

                // Menuitem for removing a force
                menu.MenuItems.Add(Messages.ForcesViewRemoveForce, (sender1, e1) =>
                    {
                        RemoveSelectedForcesFromDiagram(_forcesTable.SelectedRows);
                        IEARepository repository = EAMain.Repository;
                        _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
                    });

                // Menuitem for removing all forces
                menu.MenuItems.Add(Messages.ForcesViewRemoveAllForces, (sender1, e1) => RemoveAllForcesFromDiagram());

                Point relativeMousePosition = PointToClient(Cursor.Position);
                menu.Show(this, relativeMousePosition);
            }
        }

        /// <summary>
        ///     Cut or copy decision from the table to the clipboard
        /// </summary>
        /// <param name="selected">The selected rows to be captured</param>
        private void CopyDecisionFromDiagram(ForcesTableContext.ClipboardOperation op, IEAElement decision, int selectedColumn)
        {
            // Any previous operation is lost
            foreach(Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IForcesView> entry in _decisionsClipboard)
            {
                // Reset to default font if cut and not pasted
                _forcesTable.Columns[entry.Item2].HeaderCell.Style.Font = null;
            }
            _decisionsClipboard.Clear();

            // Get the GUID for the diagram
            IEARepository repository = EAMain.Repository;
            // Get the diagram object
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            _decisionsClipboard.Add(new Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IForcesView>(
                op, selectedColumn, diagram, decision, this));

            if (ForcesTableContext.ClipboardOperation.Cut == op)
            {
                // Mark decision as cut by changing font to italics
                DataGridViewCell c = _forcesTable.Columns[selectedColumn].HeaderCell;
                DataGridViewCellStyle style = (null != c.Style.Font) ? c.Style : _forcesTable.DefaultCellStyle;
                c.Style.Font = new Font(style.Font.Name, style.Font.Size, FontStyle.Italic);
            }
        }

        /// <summary>
        ///     Removes a decision from the table and diagram
        /// </summary>
        /// <param name="decision">The element to be removed</param>
        /// <param name="diagram">The target diagram</param>
        private void RemoveDecisionFromDiagram(IEAElement decision, IEADiagram diagram)
        {
            string diagramGuid = diagram.GUID;

            //Remove the TaggedValue of the decision
            IDecision d = Decision.Load(decision);
            d.DiagramGUID = diagram.GUID;
            if(!decision.RemoveTaggedValue(d.SerializeName(), diagramGuid))
            {
                // Legacy decisions that do not have GUID discriminator in tagged value name
                decision.RemoveTaggedValue(EATaggedValueKeys.IsDecisionElement, diagramGuid);
            }

            //Delete the element if it is not used in the diagram/table anymore
            if (!ElementExistsInDiagram(decision, diagramGuid)) diagram.RemoveElement(decision);
        }

        /// <summary>
        ///     paste captured decision selection from the clipboard to the table
        /// </summary>
        private void PasteDecisionToDiagram()
        {
            // Get the GUID for the current diagram, and the corresponding object
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IForcesView>> copiedDecisions =
                new List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IForcesView>>();

            foreach (Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IForcesView> entry in _decisionsClipboard)
            {
                if (diagramGuid == entry.Item3.GUID)
                {
                    continue;  // Same diagram, do not duplicate
                }
                // Get the decision object
                IEAElement decision = entry.Item4;

                // Add the TaggedValue of the decision
                IDecision d = Decision.Load(decision);
                d.DiagramGUID = diagram.GUID;
                decision.AddTaggedValue(d.SerializeName(), diagramGuid);

                // Add the element to the current diagram
                diagram.AddElement(decision);

                if (ForcesTableContext.ClipboardOperation.Cut == entry.Item1)
                {
                    RemoveDecisionFromDiagram(decision, entry.Item3);
                    IForcesView fv = entry.Item5;
                    fv.IsDirty = true;
                }
                else
                {
                    // Save the copied entries to be pasted again
                    copiedDecisions.Add(entry);
                }
            }
            _decisionsClipboard = copiedDecisions;

            _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
        }

        /// <summary>
        /// Remove decision selection
        /// </summary>
        /// <param name="selected"></param>
        private void RemoveDecisionFromDiagram(int selectedColumn)
        {
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            // Get the GUID for the decision
            string decisionGuid = _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells[selectedColumn].Value.ToString();

            // Get the decision object
            IEAElement decision = repository.GetElementByGUID(decisionGuid);

            RemoveDecisionFromDiagram(decision, diagram);

            _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
        }

        /// <summary>
        ///     Removes all decisions from the table and diagram
        /// </summary>
        private void RemoveAllDecisionsFromDiagram()
        {
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            for (int i = ForcesTableContext.DecisionColumnIndex; i < _forcesTable.Columns.Count; i++)
            {
                string decisionGuid = _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells[i].Value.ToString();
                IEAElement decision = EAMain.Repository.GetElementByGUID(decisionGuid);
                RemoveDecisionFromDiagram(decision, diagram);
            }
            _controller.SetDiagramModel(diagram);
        }

        /// <summary>
        ///     Cut or copy force/concern selection from the table to the clipboard
        /// </summary>
        /// <param name="selected">The selected rows to be captured</param>
        private void CopySelectedForcesFromDiagram(ForcesTableContext.ClipboardOperation op, DataGridViewSelectedRowCollection selected)
        {
            // Any previous operation is lost
            foreach (Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IEAElement, IForcesView> entry in _forcesClipboard)
            {
                // Reset to default font if cut and not pasted
                _forcesTable.Rows[entry.Item2].HeaderCell.Style.Font = _forcesTable.DefaultCellStyle.Font;
            }
            _forcesClipboard.Clear();

            // Get the GUID for the diagram
            IEARepository repository = EAMain.Repository;
            // Get the diagram object
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            foreach(DataGridViewRow selectedRow in selected)
            {
                if (_forcesTable.Rows[selectedRow.Index].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.Equals(
                    ForcesTableContext.EmptyCellValue)) continue;

                // Get the GUIDs for the force and concern
                string forceGuid =
                    _forcesTable.Rows[selectedRow.Index].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString();
                string concernGuid =
                    _forcesTable.Rows[selectedRow.Index].Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString();

                // Get the force and concern objects
                IEAElement force = repository.GetElementByGUID(forceGuid);
                IEAElement concern = repository.GetElementByGUID(concernGuid);

                _forcesClipboard.Add(new Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IEAElement, IForcesView>(
                    op, selectedRow.Index, diagram, force, concern, this));

                if(ForcesTableContext.ClipboardOperation.Cut == op)
                {
                    // Mark force as cut by changing font to italics
                    DataGridViewCell c = _forcesTable.Rows[selectedRow.Index].HeaderCell;
                    DataGridViewCellStyle style = (null != c.Style.Font) ? c.Style : _forcesTable.DefaultCellStyle;
                    c.Style.Font = new Font(style.Font.Name, style.Font.Size, FontStyle.Italic);
                }
            }
        }

        /// <summary>
        ///     Remove force/concern from the table and diagram (if necessary). Diagram should be update afterwards
        /// </summary>
        /// <param name="force">The force element to be removed</param>
        /// <param name="concern">The concern element to be removed</param>
        /// <param name="diagram">The target diagram</param>
        /// <param name="direction">The connector direction</param>
        /// <param name="fromModel">Remove connectors if true</param>,
        private void RemoveForceFromDiagram(IEAElement force, IEAElement concern, IEADiagram diagram,
            EAConnectorDirection direction = EAConnectorDirection.ClientToSupplier, bool fromModel = false)
        {
            foreach (
                IEAConnector connector in
                    force.FindConnectors(concern, EAConstants.RelationClassifiedBy, EAConstants.ForcesRelationshipType, direction))
            {
                if (connector.TaggedValueExists(EATaggedValueKeys.IsForceConnector, diagram.GUID))
                {
                    ForceConnector fc = new ForceConnector(connector.GUID);
                    fc.DiagramGUID = diagram.GUID;
                    if (!connector.RemoveTaggedValue(fc.SerializeName(), diagram.GUID))
                    {
                        // Legacy connectors that do not have GUID discriminator in tagged value name
                        connector.RemoveTaggedValue(EATaggedValueKeys.IsForceConnector, diagram.GUID);
                    }
                    if (fromModel && !connector.TaggedValueExists(EATaggedValueKeys.IsForceConnector))
                    {
                        force.RemoveConnector(connector);
                        concern.RemoveConnector(connector);
                    }
                    break;
                }
            }

            // Remove the TaggedValue of the force and concern
            Force f = new Force(force.GUID);
            f.DiagramGUID = diagram.GUID;
            if(!force.RemoveTaggedValue(f.SerializeName(), diagram.GUID))
            {
                // Legacy forces that do not have GUID discriminator in tagged value name
                force.RemoveTaggedValue(EATaggedValueKeys.IsForceElement, diagram.GUID);
            }
            Concern c = new Concern(concern.GUID);
            c.DiagramGUID = diagram.GUID;
            if(!concern.RemoveTaggedValue(c.SerializeName(), diagram.GUID))
            {
                // Legacy concerns that do not have GUID discriminator in tagged value name
                concern.RemoveTaggedValue(EATaggedValueKeys.IsConcernElement, diagram.GUID);
            }

            // Delete the element reference if it is not used in the diagram/table anymore
            if (!ElementExistsInDiagram(force, diagram.GUID)) diagram.RemoveElement(force);
            if (!ElementExistsInDiagram(concern, diagram.GUID)) diagram.RemoveElement(concern);
        }

        /// <summary>
        ///     paste captured force/concern selection from the clipboard to the table
        /// </summary>
        private void PasteSelectedForcesToDiagram()
        {
            // Get the GUID for the current diagram, and the corresponding object
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IEAElement, IForcesView>> copiedForces =
                new List<Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IEAElement, IForcesView>>();

            foreach (Tuple<ForcesTableContext.ClipboardOperation, int, IEADiagram, IEAElement, IEAElement, IForcesView> entry in _forcesClipboard)
            {
                if (diagramGuid == entry.Item3.GUID)
                {
                    continue;  // Same diagram, do not duplicate
                }
                // Get the force and concern objects
                IEAElement force = entry.Item4;
                IEAElement concern = entry.Item5;

                foreach (
                    IEAConnector connector in
                        force.FindConnectors(concern, EAConstants.RelationClassifiedBy, EAConstants.ForcesRelationshipType, EAConnectorDirection.SupplierToClient))
                {
                    if (connector.TaggedValueExists(EATaggedValueKeys.IsForceConnector, diagramGuid))
                    {
                        continue;  // Force concern pair already in diagram, do not duplicate
                    }
                    ForceConnector fc = new ForceConnector(connector.GUID);
                    fc.DiagramGUID = diagram.GUID;
                    connector.AddTaggedValue(fc.SerializeName(), diagramGuid);
                }

                // Add the TaggedValue of the force and concern
                Force f = new Force(force.GUID);
                f.DiagramGUID = diagram.GUID;
                force.AddTaggedValue(f.SerializeName(), diagramGuid);
                Concern c = new Concern(concern.GUID);
                c.DiagramGUID = diagram.GUID;
                concern.AddTaggedValue(c.SerializeName(), diagramGuid);

                // Add the elements to the current diagram
                diagram.AddElement(force);
                diagram.AddElement(concern);

                if(ForcesTableContext.ClipboardOperation.Cut == entry.Item1)
                {
                    RemoveForceFromDiagram(force, concern, entry.Item3, EAConnectorDirection.SupplierToClient);
                    IForcesView fv = entry.Item6;
                    fv.IsDirty = true;
                }
                else
                {
                    // Save the copied entries to be pasted again
                    copiedForces.Add(entry);
                }
            }
            _forcesClipboard = copiedForces;

            _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
        }

        /// <summary>
        /// Remove force/concern selection
        /// </summary>
        /// <param name="selected"></param>
        private void RemoveSelectedForcesFromDiagram(DataGridViewSelectedRowCollection selected)
        {
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            foreach (DataGridViewRow selectedRow in selected)
            {
                if (_forcesTable.Rows[selectedRow.Index].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.Equals(
                    ForcesTableContext.EmptyCellValue)) continue;

                // Get the GUIDs for the force and concern
                string forceGuid =
                    _forcesTable.Rows[selectedRow.Index].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString();
                string concernGuid =
                    _forcesTable.Rows[selectedRow.Index].Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString();

                // Get the force and concern objects
                IEAElement force = repository.GetElementByGUID(forceGuid);
                IEAElement concern = repository.GetElementByGUID(concernGuid);

                RemoveForceFromDiagram(force, concern, diagram, EAConnectorDirection.ClientToSupplier, true);
            }

            _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
        }

        private void RemoveAllForcesFromDiagram()
        {
            IEARepository repository = EAMain.Repository;
            string diagramGuid = _controller.Model.DiagramGUID;
            IEADiagram diagram = repository.GetDiagramByGuid(diagramGuid);

            for (int i = _forcesTable.Rows.Count - 1; i >= 0; i--)
            {
                if (
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.Equals(
                        ForcesTableContext.EmptyCellValue)) continue;

                // Get the GUIDs for the force and concern
                string forceGuid =
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString();
                string concernGuid =
                    _forcesTable.Rows[i].Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString();

                // Get the force and concern objects
                IEAElement force = repository.GetElementByGUID(forceGuid);
                IEAElement concern = repository.GetElementByGUID(concernGuid);

                RemoveForceFromDiagram(force, concern, diagram, EAConnectorDirection.ClientToSupplier, true);
            }

            _controller.SetDiagramModel(repository.GetDiagramByGuid(_controller.Model.DiagramGUID));
        }

        /// <summary>
        ///     Checks if element el exists in the diagram, with GUID diagramGuid, as a decision, force or concern by looking at its taggedvalues
        /// </summary>
        /// <param name="el"></param>
        /// <param name="diagramGuid"></param>
        /// <returns></returns>
        private bool ElementExistsInDiagram(IEAElement el, string diagramGuid)
        {
            return el.TaggedValueExists(EATaggedValueKeys.IsForceElement, diagramGuid) ||
                   el.TaggedValueExists(EATaggedValueKeys.IsDecisionElement, diagramGuid) ||
                   el.TaggedValueExists(EATaggedValueKeys.IsConcernElement, diagramGuid);
        }

        private void OpenInDetailView(IDecision decision)
        {
            DetailViewHandler.Instance.OpenDecisionDetailView(decision);
        }

        private void _btnConfigure_Click(object sender, EventArgs e)
        {
            _controller.Configure();
        }

        private void _btnOpenExcel_Click(object sender, EventArgs e)
        {
            new ExcelSynchronization(_controller, _forcesTable);
        }

        private void _btnAddDecision_Click(object sender, EventArgs e)
        {
            var addDecision = new AddDecision(_controller);
            addDecision.ShowDialog();
        }

        private void _btnAddForce_Click(object sender, EventArgs e)
        {
            var addForce = new AddForce(_controller);
            addForce.ShowDialog();
        }

        /// <summary>
        /// Handler for clicks in forces table, especially to show related elements in the project broswer and update
        /// the tagged values for editing.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _forcesTable_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            string guid = "";
            if (0 > e.RowIndex)
            {
                if(1 < _forcesTable.Rows.Count && 0 <= e.ColumnIndex)
                {
                    // Show decision in project browser, element GUID is stored in the last row of the table
                    guid = _forcesTable.Rows[_forcesTable.Rows.Count - 1].Cells[e.ColumnIndex].Value.ToString();
                }
            }
            else
            {
                DataGridViewRow row = _forcesTable.Rows[e.RowIndex];
                if (row.HeaderCell == null) return;

                if (0 > e.ColumnIndex)
                {
                    // Show force in project browser, element GUID is stored in well-known column of table
                    guid = row.Cells[ForcesTableContext.ForceGUIDColumnIndex].Value.ToString();
                }
                else if (ForcesTableContext.ConcernColumnIndex == e.ColumnIndex)
                {
                    // Show concern in project browser, element GUID is stored in well-known column of table
                    guid = row.Cells[ForcesTableContext.ConcernGUIDColumnIndex].Value.ToString();
                }
            }

            if (0 >= guid.Length || guid.Equals(ForcesTableContext.EmptyCellValue)) return;
            IEARepository repository = EAMain.Repository;
            IEAElement element = repository.GetElementByGUID(guid);
            if (element != null)
            {
                element.ShowInProjectView();
            }
        }

        private void _chkShowScenarios_CheckedChanged(object sender, EventArgs e)
        {
            _controller.Model.ScenarioView = _chkShowScenarios.Checked;
            UpdateTable(_controller.Model);
        }

        private void _forcesTable_CellMouseClick(object sender, DataGridViewCellMouseEventArgs e)
        {
            if(0 > e.RowIndex && 0 > e.ColumnIndex)
            {
                // Top left cell
                if (e.Button == MouseButtons.Right)
                {
                    if(0 < _forcesClipboard.Count() || 0 < _decisionsClipboard.Count())
                    {
                        var menu = new ContextMenu();
                        if (0 < _forcesClipboard.Count())
                        {
                            // Menuitem for pasting forces
                            menu.MenuItems.Add(Messages.ForcesViewPasteForce, (sender1, e1) => PasteSelectedForcesToDiagram());
                        }
                        if (0 < _decisionsClipboard.Count())
                        {
                            // Menuitem for pasting forces
                            menu.MenuItems.Add(Messages.ForcesViewPasteDecision, (sender1, e1) => PasteDecisionToDiagram());
                        }

                        Point relativeMousePosition = PointToClient(Cursor.Position);
                        menu.Show(this, relativeMousePosition);
                    }
                }
            }
        }
    }
}